package com.informationsystem.model;

import com.informationsystem.model.BaseObject;

import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
import org.hibernate.search.annotations.DocumentId;
import org.hibernate.search.annotations.Field;
import org.hibernate.search.annotations.Indexed;
import org.hibernate.search.annotations.IndexedEmbedded;

import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;

import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;

import javax.xml.bind.annotation.XmlRootElement;

import java.io.Serializable;

@Entity
@Table(name="systemuser", uniqueConstraints = @UniqueConstraint(columnNames="username") )
@Indexed
@XmlRootElement
public class Systemuser extends BaseObject implements Serializable {
    private Long id;
    private String username;
    private String password;
    private String name;
    private String type;
    private Set<Notice> notices = new HashSet<Notice>(0);
    private Set<News> newses = new HashSet<News>(0);
    private Set<Video> videos = new HashSet<Video>(0);
    private Set<Downloads> downloads = new HashSet<Downloads>(0);
    private Set<Event> event = new HashSet<Event>(0);
    private Set<Log> logs = new HashSet<Log>(0);
    private Set<Authority> authorities = new HashSet<Authority>(0);

    @Id @GeneratedValue(strategy=IDENTITY) @DocumentId    
    public Long getId() {
        return this.id;
    }
    
    public void setId(Long id) {
        this.id = id;
    }
    
    @Column(name="username", unique=true, nullable=false, length=50)
    @Field
    public String getUsername() {
        return this.username;
    }
    
    public void setUsername(String username) {
        this.username = username;
    }
    
    @Column(name="password", nullable=false, length=50)
    @Field
    public String getPassword() {
        return this.password;
    }
    
    public void setPassword(String password) {
        this.password = password;
    }
    
    @Column(name="name", length=50)
    @Field
    public String getName() {
        return this.name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    @Column(name="type", nullable=false, length=20)
    @Field
    public String getType() {
        return this.type;
    }
    
    public void setType(String type) {
        this.type = type;
    }

@OneToMany(cascade=CascadeType.REMOVE, fetch=FetchType.EAGER, mappedBy="systemuser")
@Fetch(value = FetchMode.SUBSELECT)
    public Set<Log> getLogs() {
        return this.logs;
    }
    
    public void setLogs(Set<Log> logs) {
        this.logs = logs;
    }
    
	@ManyToMany(cascade = {CascadeType.REFRESH, CascadeType.MERGE}, fetch=FetchType.EAGER)
	    @JoinTable(name="authority2user", joinColumns = { 
	        @JoinColumn(name="user_id", nullable=false, updatable=false) }, inverseJoinColumns = { 
	        @JoinColumn(name="authority_id", nullable=false, updatable=false) })
	@Fetch(value = FetchMode.SUBSELECT)
    public Set<Authority> getAuthorities() {
        return this.authorities;
    }
    
    public void setAuthorities(Set<Authority> authorities) {
        this.authorities = authorities;
    }

    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Systemuser pojo = (Systemuser) o;

        if (username != null ? !username.equals(pojo.username) : pojo.username != null) return false;
        if (password != null ? !password.equals(pojo.password) : pojo.password != null) return false;
        if (name != null ? !name.equals(pojo.name) : pojo.name != null) return false;
        if (type != null ? !type.equals(pojo.type) : pojo.type != null) return false;

        return true;
    }

    public int hashCode() {
        int result = 0;
        result = (username != null ? username.hashCode() : 0);
        result = 31 * result + (password != null ? password.hashCode() : 0);
        result = 31 * result + (name != null ? name.hashCode() : 0);
        result = 31 * result + (type != null ? type.hashCode() : 0);

        return result;
    }

    public String toString() {
        StringBuffer sb = new StringBuffer(getClass().getSimpleName());

        sb.append(" [");
        sb.append("id").append("='").append(getId()).append("', ");
        sb.append("username").append("='").append(getUsername()).append("', ");
        sb.append("password").append("='").append(getPassword()).append("', ");
        sb.append("name").append("='").append(getName()).append("', ");
        sb.append("type").append("='").append(getType()).append("', ");
        
        
        
        sb.append("]");
      
        return sb.toString();
    }
    
    @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER, mappedBy="systemuser")
    @Fetch(value = FetchMode.SUBSELECT)
	public Set<Notice> getNotices() {
		return notices;
	}

	public void setNotices(Set<Notice> notices) {
		this.notices = notices;
	}
	
	@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER, mappedBy="systemuser")
	@Fetch(value = FetchMode.SUBSELECT)
	public Set<News> getNewses() {
		return newses;
	}

	public void setNewses(Set<News> newses) {
		this.newses = newses;
	}
	
	@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER, mappedBy="systemuser")
	@Fetch(value = FetchMode.SUBSELECT)
	public Set<Video> getVideos() {
		return videos;
	}

	public void setVideos(Set<Video> videos) {
		this.videos = videos;
	}
	
	@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER, mappedBy="systemuser")
	@Fetch(value = FetchMode.SUBSELECT)
	public Set<Downloads> getDownloads() {
		return downloads;
	}

	public void setDownloads(Set<Downloads> downloads) {
		this.downloads = downloads;
	}
	@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER, mappedBy="systemuser")
	@Fetch(value = FetchMode.SUBSELECT)
	public Set<Event> getEvent() {
		return event;
	}

	public void setEvent(Set<Event> event) {
		this.event = event;
	}

}
